package rstplus;

/*
 * RST - Russian SMS transliterator
 * Copyleft 2011
 * Author: Alexey Shat'ko (Алексей Шатько), rstapp@yandex.ru
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this source code (in file copying.txt); if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.RecordStoreException;

public class RSTPMIDlet extends MIDlet implements CommandListener {

    private static final String ABOUT_TEXT =
            "Russian SMS Transliterator v 0.3.0 (testing). Программа предназначена"
            + " для отправки SMS на русском языке в транслитерации. "
            + "Программа не использует интернет и короткие номера, сообщение "
            + "отправляется непосредственно с Вашего телефона непосредственно "
            + "на номер адресата. Программа распространяется бесплатно по условиям "
            + "лицензии GPL v.2 или более поздней версии GPL. Автор Алексей "
            + "Шатько (Alexey Shat'ko). Подробная информация "
            + "http://code.google.com/p/rusmstranslitplus/ или rstapp.narod.ru.";
    private boolean neverSentFlag = true;
    private boolean paused = false;
    private Display disp = null;
    private DisplayableStack dispStack;
    private boolean swapButtons = false;
    private Command okCommand;
    private Command exitCommand;
    private Command cancelCommand;
    private Command backCommand;
    private Form mainForm;
    private StringItem translitItem;
    private Command editCommand;
    private Command sendCommand;
    private Command translitToEditorCommand;
    private Command historyCommand;
    private Command settingsCommand;
    private Command aboutCommand;
    private TextBox editBox;
    private Command saveDraftCommand;
    private Command draftsCommand;
    private Command clearTextCommand;
    private String sourceText = "";
    private String translitText = "";
    private String sentText = null;
    private MessageBox clearTextWarning;
    private static final int EDITOR_SIZE = 456;
    private static final int NUMBER_MAX_LENGTH = 20;

    public void startApp() {
        if (paused) {
            paused = false;
        } else {
            disp = Display.getDisplay(this);
            __init();
        }
    }

    public void pauseApp() {
        paused = true;
        disp.setCurrent(null);
    }

    public void destroyApp(boolean unconditional) {
        if (!unconditional) {
            pauseApp();
        } else {
            __finalize();
            notifyDestroyed();
        }
    }

    private void __init() {
        mainForm = new Form("");
        String draftText;
        try {
            draftText = DraftStorage.read();
        } catch (Exception exc) {
            draftText = null;
        }
        try {
            SettingsManager.load();
            PhonebookStorage.setEnabled(SettingsManager.isPhonebookEnabled());
            HistoryStorage.setEnabled(SettingsManager.getHistorySize() != 0);
            TranslitAlgorithm.set4Used(SettingsManager.isUse4());
            TranslitAlgorithm.setXUsed(SettingsManager.isUseX());
            TranslitAlgorithm.setSoftSignOmited(SettingsManager.isOmitSoftSign());
        } catch (Exception exc) {
            try {
                SettingsManager.clear();
            } catch (Exception exc1) {
                //Skip
            }
            Alert a = new Alert("Ошибка", "Ошибка при инициализации приложения", null,
                    AlertType.ERROR);
            disp.setCurrent(a, mainForm);
        }
        swapButtons = SettingsManager.isSwapButtons();
        exitCommand = new Command("Выход", Command.EXIT, 100);
        translitItem = new StringItem("", "");
        mainForm.append(translitItem);
        editCommand = new Command("Редакт.", swapButtons ? Command.BACK : Command.OK, 10);
        cancelCommand = new Command("Отмена", swapButtons ? Command.OK : Command.CANCEL, 90);
        backCommand = new Command("Назад", swapButtons ? Command.OK : Command.BACK, 90);
        okCommand = new Command("ОК", swapButtons ? Command.BACK : Command.OK, 10);
        sendCommand = new Command("Отправить...", Command.SCREEN, 20);
        historyCommand = new Command("Отправленные", Command.SCREEN, 30);
        translitToEditorCommand = new Command("Транслит в редактор", Command.SCREEN, 40);
        settingsCommand = new Command("Настройки...", Command.SCREEN, 50);
        aboutCommand = new Command("О программе...", Command.SCREEN, 80);
        mainForm.addCommand(editCommand);
        mainForm.addCommand(sendCommand);
        mainForm.addCommand(translitToEditorCommand);
        if (HistoryStorage.isEnabled()) {
            mainForm.addCommand(historyCommand);
        }
        mainForm.addCommand(settingsCommand);
        mainForm.addCommand(aboutCommand);
        mainForm.addCommand(exitCommand);
        mainForm.setCommandListener(this);
        editBox = new TextBox("RST", "", EDITOR_SIZE, TextField.ANY);
        saveDraftCommand = new Command("Сохр. черновик", Command.SCREEN, 30);
        draftsCommand = new Command("Черновики", Command.SCREEN, 40);
        clearTextCommand = new Command("Очистить", Command.SCREEN, 50);
        editBox.addCommand(okCommand);
        editBox.addCommand(saveDraftCommand);
        editBox.addCommand(draftsCommand);
        editBox.addCommand(clearTextCommand);
        editBox.addCommand(aboutCommand);
        editBox.setCommandListener(this);
        dispStack = new DisplayableStack(disp, mainForm);
        if ((draftText != null) && (draftText.length() > 0)) {
            setText(draftText);
            sentText = draftText;
        } else {
            setText("");
        }
        dispStack.push(editBox);
    }

    private void __finalize() {
        try {
            setTextFormEditor();
            if (neverSentFlag || ((sentText == null) && (sourceText.length() > 0))) {
                DraftStorage.set(sourceText);
            } else {
                DraftStorage.set(null);
            }
        } catch (Exception exc) {
            //Skip
        }
    }

    private void setTextFormEditor() {
        sourceText = editBox.getString();
        if (sentText != null) {
            if (!sentText.equals(sourceText)) {
                sentText = null;
            }
        }
        translitText = TranslitAlgorithm.transliterate(sourceText);
        SMSSender.PartsCount translitPartsCount = SMSSender.getPartsCount(translitText);
        mainForm.setTitle("TR " + translitPartsCount.toString()
                + " RU " + SMSSender.getPartsCount(sourceText).toString1(translitPartsCount));
        translitItem.setText(translitText);
    }

    private void setText(String text) {
        if (!editBox.getString().equals(text)) {
            String textForEditor = (text.length() > EDITOR_SIZE) ? text.substring(0, EDITOR_SIZE) : text;
            editBox.setString(textForEditor);
        }
        sourceText = text;
        translitText = TranslitAlgorithm.transliterate(text);
        SMSSender.PartsCount translitPartsCount = SMSSender.getPartsCount(translitText);
        mainForm.setTitle("TR " + translitPartsCount.toString()
                + " RU " + SMSSender.getPartsCount(sourceText).toString1(translitPartsCount));
        translitItem.setText(translitText);
    }

    public void commandAction(Command c, Displayable d) {
        if (c == aboutCommand) {
            MessageBox aboutBox = new MessageBox("О программе", ABOUT_TEXT, false);
            dispStack.push(aboutBox);
            return;
        }
        if (d == mainForm) {
            if (c == editCommand) {
                dispStack.push(editBox);
            } else if (c == exitCommand) {
                destroyApp(true);
            } else if (c == sendCommand) {
                if (translitText.length() == 0) {
                    MessageBox errBox = new MessageBox("Ошибка",
                            "Нельзя отправить пустое сообщение", false);
                    dispStack.push(errBox);
                    return;
                }
                dispStack.push(new SendBox());
            } else if (c == translitToEditorCommand) {
                setText(translitText);
                dispStack.push(editBox);
            } else if (c == historyCommand) {
                if (HistoryStorage.isEnabled()) {
                    try {
                        dispStack.push(new HistoryBox());
                    } catch (Exception exc) {
                        MessageBox mb = new MessageBox("Ошибка", "Ошибка при загрузке истории", false);
                        dispStack.push(mb);
                    }
                }
            } else if (c == settingsCommand) {
                dispStack.push(new SettingsForm());
            }
        } else if (d == editBox) {
            if (c == okCommand) {
                dispStack.pop();
                setTextFormEditor();
            } else if (c == saveDraftCommand) {
                try {
                    String text = editBox.getString();
                    if (text.length() == 0) {
                        return;
                    }
                    SavedDraftsStorage.addRecord(text);
                    MessageBox mb = new MessageBox("Сообщение", "Черновик сохранен", false);
                    dispStack.push(mb);
                } catch (RecordStoreException exc) {
                    MessageBox mb = new MessageBox("Ошибка", "Ошибка при сохранении черновика", false);
                    dispStack.push(mb);
                }
            } else if (c == draftsCommand) {
                try {
                    dispStack.push(new DraftsList());
                } catch (RecordStoreException exc) {
                    dispStack.push(new MessageBox("Ошибка", "Ошибка при загрузке черновиков", false));
                }
            } else if (c == clearTextCommand) {
                clearTextWarning = new MessageBox("Вопрос", "Удалить весь набранный текст?", true);
                clearTextWarning.setCommandListener(this);
                dispStack.push(clearTextWarning);
            }
        } else if (d == clearTextWarning) {
            if (c == okCommand) {
                setText("");
                clearTextWarning = null;
                dispStack.pop();
            } else if (c == cancelCommand) {
                clearTextWarning = null;
                dispStack.pop();
            }
        }
    }

    private void applySettings() {
        TranslitAlgorithm.set4Used(SettingsManager.isUse4());
        TranslitAlgorithm.setXUsed(SettingsManager.isUseX());
        TranslitAlgorithm.setSoftSignOmited(SettingsManager.isOmitSoftSign());
        swapButtons = SettingsManager.isSwapButtons();
        setTextFormEditor();
        PhonebookStorage.setEnabled(SettingsManager.isPhonebookEnabled());
        int hsize = SettingsManager.getHistorySize();
        boolean historyEnabledOld = HistoryStorage.isEnabled();
        if (hsize == 0) {
            HistoryStorage.setEnabled(false);
            if (historyEnabledOld) {
                mainForm.removeCommand(historyCommand);
            }
        } else {
            HistoryStorage.setEnabled(true);
            try {
                HistoryStorage.trim();
            } catch (RecordStoreException exc) {
                //skip
            }
            if (!historyEnabledOld) {
                mainForm.addCommand(historyCommand);
            }
        }
    }

    private final class SettingsForm extends Form implements CommandListener {

        private ChoiceGroup cgTranslitOptions;
        private TextField tfHistorySize;
        private ChoiceGroup cgOtherOptions;

        public SettingsForm() {
            super("Настройки");
            cgTranslitOptions = new ChoiceGroup("Опции транслитерации", ChoiceGroup.MULTIPLE);
            cgTranslitOptions.append("X вместо КС", null);
            cgTranslitOptions.append("4 вместо Ч", null);
            cgTranslitOptions.append("Пропускать мягкие и твердые знаки", null);
            cgTranslitOptions.setSelectedIndex(0, SettingsManager.isUseX());
            cgTranslitOptions.setSelectedIndex(1, SettingsManager.isUse4());
            cgTranslitOptions.setSelectedIndex(2, SettingsManager.isOmitSoftSign());
            this.append(cgTranslitOptions);
            this.append("При установке нуля в качестве размера истории хранение "
                    + "отправленных сообщений будет отключено, вся история будет удалена!");
            tfHistorySize = new TextField("Размер истории (0-99)",
                    String.valueOf(SettingsManager.getHistorySize()),
                    2, TextField.NUMERIC);
            this.append(tfHistorySize);
            this.append("После изменении настроек из следующей группы следует"
                    + " перезапустить приложение! При отключении телефонной книги приложения"
                    + " все ее записи будут удалены!");
            cgOtherOptions = new ChoiceGroup("Другие настройки", ChoiceGroup.MULTIPLE);
            cgOtherOptions.append("Поменять местами ОК и Отмена", null);
            cgOtherOptions.append("Включить собственную телефонную книгу приложения", null);
            cgOtherOptions.setSelectedIndex(0, SettingsManager.isSwapButtons());
            cgOtherOptions.setSelectedIndex(1, SettingsManager.isPhonebookEnabled());
            this.append(cgOtherOptions);
            this.addCommand(okCommand);
            this.addCommand(cancelCommand);
            this.setCommandListener(this);
        }

        public void commandAction(Command c, Displayable d) {
            if (d == this) {
                if (c == okCommand) {
                    boolean[] translitOptions = new boolean[3];
                    cgTranslitOptions.getSelectedFlags(translitOptions);
                    boolean _useX = translitOptions[0];
                    boolean _use4 = translitOptions[1];
                    boolean _omitSoftSign = translitOptions[2];
                    int _historySize;
                    boolean[] otherOptions = new boolean[2];
                    cgOtherOptions.getSelectedFlags(otherOptions);
                    boolean _swapButtons = otherOptions[0];
                    boolean _enablePhonebook = otherOptions[1];
                    try {
                        _historySize = Integer.parseInt(tfHistorySize.getString());
                        if ((_historySize < 0) || (_historySize > 99)) {
                            throw new Exception();
                        }
                    } catch (Exception exc) {
                        MessageBox mb = new MessageBox("Ошибка", "Неправильный ввод", false);
                        dispStack.push(mb);
                        return;
                    }
                    SettingsManager.setUseX(_useX);
                    SettingsManager.setUse4(_use4);
                    SettingsManager.setOmitSoftSign(_omitSoftSign);
                    SettingsManager.setHistorySize(_historySize);
                    SettingsManager.setSwapButtons(_swapButtons);
                    SettingsManager.setPhonebookEnabled(_enablePhonebook);
                    try {
                        SettingsManager.save();
                        applySettings();
                    } catch (Exception exc) {
                        try {
                            SettingsManager.clear();
                            applySettings();
                        } catch (Exception exc1) {
                            //Skip
                        }
                        MessageBox mb = new MessageBox("Ошибка",
                                "Ошибка при сохранении настроек", false);
                        dispStack.pop();
                        dispStack.push(mb);
                        return;
                    }
                    dispStack.pop();
                } else {
                    dispStack.pop();
                }
            }
        }
    }

    private final class SendBox extends TextBox implements CommandListener {

        private Command phonebookCommand;
        private Command sendSourceCommand;
        private MessageBox mbSendResult;
        private MessageBox mbSendAsIsWarning;

        public SendBox() {
            super("Номер для отправки", "", NUMBER_MAX_LENGTH, TextField.PHONENUMBER);
            this.addCommand(cancelCommand);
            this.addCommand(okCommand);
            if (SettingsManager.isPhonebookEnabled()) {
                phonebookCommand = new Command("Телефонная книга", Command.SCREEN, 20);
                this.addCommand(phonebookCommand);
            }
            if (SMSSender.getPartsCount(sourceText).getCount() != SMSSender.TOO_MANY_PARTS) {
                sendSourceCommand = new Command("Отправить без транслитерации", Command.SCREEN, 30);
                this.addCommand(sendSourceCommand);
            }
            this.setCommandListener(this);
        }

        private boolean send(boolean source) {
            Alert a = new Alert("", "Отправка...", null, AlertType.INFO);
            disp.setCurrent(a, disp.getCurrent());
            String textToSend = source ? sourceText : translitText;
            String number = this.getString();
            int result = SMSSender.send(textToSend, number);
            switch (result) {
                case SMSSender.OK:
                    sentText = sourceText;
                    neverSentFlag = false;
                    mbSendResult = new MessageBox("Информация", "Сообщение успешно отправлено", false);
                    try {
                        saveToHistory(textToSend, sourceText, number);
                    } catch (RecordStoreException exc) {
                        mbSendResult = new MessageBox("Ошибка", "Сообщение отправлено, "
                                + "но при сохранении в историю произошла ошбика", false);
                    }
                    mbSendResult.setCommandListener(this);
                    dispStack.push(mbSendResult);
                    return true;
                case SMSSender.INVALID_NUMBER:
                    mbSendResult = new MessageBox("Ошибка", "Некорректный номер", false);
                    dispStack.push(mbSendResult);
                    mbSendResult.setCommandListener(this);
                    return false;
                case SMSSender.TOO_LONG_MESSAGE:
                    mbSendResult = new MessageBox("Ошибка", "Слишком длинное сообщение", false);
                    dispStack.push(mbSendResult);
                    mbSendResult.setCommandListener(this);
                    return true;
                case SMSSender.ERROR:
                    mbSendResult = new MessageBox("Ошибка", "Ошибка при отправке сообщения", false);
                    dispStack.push(mbSendResult);
                    mbSendResult.setCommandListener(this);
                    return false;
                default:
                    return false;
            }
        }

        private void saveToHistory(String sent, String source, String number) throws RecordStoreException {
            HistoryStorage.add(sent, source, number);
        }
        private boolean popFlag = false;

        public void commandAction(Command c, Displayable d) {
            if (d == this) {
                if (c == cancelCommand) {
                    dispStack.pop();
                } else if (c == okCommand) {
                    popFlag = send(false);
                } else if (c == phonebookCommand) {
                    PhonebookList list;
                    try {
                        list = new PhonebookList();
                    } catch (Exception exc) {
                        popFlag = false;
                        mbSendResult = new MessageBox("Ошибка", "Ошибка загрузки телефонной книги", false);
                        mbSendResult.setCommandListener(this);
                        dispStack.push(mbSendResult);
                        return;
                    }
                    dispStack.push(list);
                } else if (c == sendSourceCommand) {
                    int count = SMSSender.getPartsCount(sourceText).getCount();
                    String warnStr = "Отправить без транслитерации?";
                    switch (count) {
                        case 1:
                            warnStr = "Отправить 1 сообщение без транслитерации?";
                            break;
                        case 2:
                            warnStr = "Отправить 2 сообщения без транслитерации?";
                            break;
                        case 3:
                            warnStr = "Отправить 3 сообщения без транслитерации?";
                    }
                    mbSendAsIsWarning = new MessageBox("Предупреждение", warnStr, true);
                    mbSendAsIsWarning.setCommandListener(this);
                    dispStack.push(mbSendAsIsWarning);
                }
            } else if (d == mbSendResult) {
                if (popFlag) {
                    dispStack.pop(2);
                } else {
                    dispStack.pop();
                }
            } else if (d == mbSendAsIsWarning) {
                if (c == okCommand) {
                    dispStack.pop();
                    popFlag = send(true);
                } else if (c == cancelCommand) {
                    dispStack.pop();
                }
            }
        }

        private final class PhonebookList extends List implements CommandListener {

            private Command newRecordCommand;
            private Command editRecordCommand;
            private Command deleteRecordCommand;
            private MessageBox deleteWarningBox;
            private Form recordForm = null;
            private TextField nameField;
            private TextField numberField;
            private boolean changedFlag = false;
            private int currentEditIndex = -1;
            private static final int NAME_MAX_LENGTH = 30;

            public PhonebookList() throws RecordStoreException {
                super("Телефонная книга", List.IMPLICIT);
                if (!SettingsManager.isPhonebookEnabled()) {
                    throw new RuntimeException();
                }
                PhonebookStorage.load();
                addCommand(okCommand);
                addCommand(backCommand);
                newRecordCommand = new Command("Новая запись", Command.SCREEN, 30);
                editRecordCommand = new Command("Редактировать", Command.SCREEN, 40);
                deleteRecordCommand = new Command("Удалить", Command.SCREEN, 50);
                addCommand(newRecordCommand);
                addCommand(editRecordCommand);
                addCommand(deleteRecordCommand);
                setSelectCommand(okCommand);
                this.setCommandListener(this);
                load();
            }

            private void load() {
                deleteAll();
                int count = PhonebookStorage.getItemsCount();
                for (int i = 0; i < count; i++) {
                    append(PhonebookStorage.getItem(i).getName(), null);
                }
            }

            private void initRecordForm(String name, String number) {
                if (recordForm == null) {
                    recordForm = new Form((currentEditIndex < 0) ? "Новая запись" : "Редактирование");
                    nameField = new TextField("Имя", (name == null) ? "" : name,
                            NAME_MAX_LENGTH, TextField.NON_PREDICTIVE);
                    numberField = new TextField("Номер", (number == null) ? "" : number,
                            NUMBER_MAX_LENGTH, TextField.PHONENUMBER);
                    recordForm.append(nameField);
                    recordForm.append(numberField);
                    recordForm.addCommand(okCommand);
                    recordForm.addCommand(backCommand);
                    recordForm.setCommandListener(this);
                } else {
                    nameField.setString((name == null) ? "" : name);
                    numberField.setString((number == null) ? "" : number);
                }
            }

            private void nullRecordForm() {
                recordForm = null;
                nameField = null;
                numberField = null;
            }

            public void commandAction(Command c, Displayable d) {
                if (d == this) {
                    int currentIndex = this.getSelectedIndex();
                    if (c == okCommand) {
                        if (currentIndex >= 0) {
                            SendBox.this.setString(PhonebookStorage.getItem(currentIndex).getNumber());
                        }
                    }
                    if ((c == okCommand) || (c == backCommand)) {
                        dispStack.pop();
                        if (changedFlag) {
                            try {
                                PhonebookStorage.save();
                            } catch (RecordStoreException exc) {
                                dispStack.push(new MessageBox("Ошибка",
                                        "Ошибка при сохранении телефонной книги", false));
                            }
                        }
                        PhonebookStorage.unload();
                    } else if (c == newRecordCommand) {
                        initRecordForm(null, null);
                        currentEditIndex = -1;
                        dispStack.push(recordForm);
                    } else if (c == editRecordCommand) {
                        if (currentIndex < 0) {
                            return;
                        }
                        PhonebookStorage.PhonebookItem item = PhonebookStorage.getItem(currentIndex);
                        currentEditIndex = currentIndex;
                        initRecordForm(item.getName(), item.getNumber());
                        dispStack.push(recordForm);
                    } else if (c == deleteRecordCommand) {
                        if (currentIndex < 0) {
                            return;
                        }
                        deleteWarningBox = new MessageBox("Вопрос", "Удалить запись \""
                                + PhonebookStorage.getItem(currentIndex).getName() + "\"?", true);
                        currentEditIndex = currentIndex;
                        deleteWarningBox.setCommandListener(this);
                        dispStack.push(deleteWarningBox);
                    }
                } else if (d == recordForm) {
                    if (c == okCommand) {
                        String name = nameField.getString();
                        String number = numberField.getString();
                        if ((name.length() == 0) || (!SMSSender.checkNumber(number))) {
                            MessageBox mb = new MessageBox("Ошибка", "Неправильный ввод", false);
                            dispStack.push(mb);
                            return;
                        }
                        if (currentEditIndex < 0) {
                            PhonebookStorage.addItem(name, number);
                        } else {
                            PhonebookStorage.PhonebookItem item =
                                    PhonebookStorage.getItem(currentEditIndex);
                            item.setName(name);
                            item.setNumber(number);
                        }
                        PhonebookStorage.sort();
                        load();
                        dispStack.pop();
                        changedFlag = true;
                    } else if (c == backCommand) {
                        dispStack.pop();
                        nullRecordForm();
                    }
                } else if (d == deleteWarningBox) {
                    if (c == okCommand) {
                        PhonebookStorage.deleteItem(currentEditIndex);
                        PhonebookStorage.sort();
                        load();
                        dispStack.pop();
                        changedFlag = true;
                    } else if (c == cancelCommand) {
                        dispStack.pop();
                    }
                }
            }
        }
    }

    private final class DraftsList extends List implements CommandListener {

        private int currentIndex = -1;
        private SavedDraftsStorage.SavedDraft openItem;
        private Form itemForm;
        private StringItem textStringItem;
        private Command deleteCommand;
        private Command clearCommand;
        private MessageBox clearWarning = null;

        public DraftsList() throws RecordStoreException {
            super("Черновики", List.IMPLICIT);
            SavedDraftsStorage.load();
            load();
            clearCommand = new Command("Удалить все", Command.SCREEN, 30);
            addCommand(okCommand);
            addCommand(backCommand);
            addCommand(clearCommand);
            setSelectCommand(okCommand);
            setCommandListener(this);
            itemForm = new Form("");
            textStringItem = new StringItem(null, null);
            deleteCommand = new Command("Удалить", Command.SCREEN, 30);
            itemForm.append(textStringItem);
            itemForm.addCommand(okCommand);
            itemForm.addCommand(backCommand);
            itemForm.addCommand(deleteCommand);
            itemForm.setCommandListener(this);
        }

        private void load() {
            deleteAll();
            int count = SavedDraftsStorage.getItemsCount();
            for (int i = count - 1; i >= 0; i--) {
                append(SavedDraftsStorage.getItem(i).getShortText(), null);
            }
        }

        public void commandAction(Command c, Displayable d) {
            if (d == this) {
                if (c == okCommand) {
                    currentIndex = getSelectedIndex();
                    if (currentIndex < 0) {
                        return;
                    }
                    int index = SavedDraftsStorage.getItemsCount() - currentIndex - 1;
                    try {
                        SavedDraftsStorage.getFullText(index);
                    } catch (RecordStoreException exc) {
                        dispStack.push(new MessageBox("Ошбика", "Ошибка при загрузке черновика", false));
                        return;
                    }
                    openItem = SavedDraftsStorage.getItem(index);
                    itemForm.setTitle(openItem.getDate().toString());
                    textStringItem.setText(openItem.getText());
                    dispStack.push(itemForm);
                } else if (c == backCommand) {
                    SavedDraftsStorage.unload();
                    dispStack.pop();
                } else if (c == clearCommand) {
                    if (clearWarning == null) {
                        clearWarning = new MessageBox("Вопрос", "Удалить все черновики?", true);
                    }
                    clearWarning.setCommandListener(this);
                    dispStack.push(clearWarning);
                }
            } else if (d == itemForm) {
                if (c == okCommand) {
                    setText(openItem.getText());
                    SavedDraftsStorage.unload();
                    dispStack.popAll();
                    dispStack.push(editBox);
                } else if (c == backCommand) {
                    dispStack.pop();
                } else if (c == deleteCommand) {
                    try {
                        SavedDraftsStorage.deleteRecord(SavedDraftsStorage.getItemsCount() - currentIndex - 1);
                        load();
                    } catch (RecordStoreException exc) {
                        dispStack.pop();
                        dispStack.push(new MessageBox("Ошибка", "Ошибка при выполнении операции", false));
                        return;
                    }
                    dispStack.pop();
                }
            } else if (d == clearWarning) {
                if (c == okCommand) {
                    try {
                        SavedDraftsStorage.deleteAll();
                    } catch (RecordStoreException exc) {
                        dispStack.pop(2);
                        dispStack.push(new MessageBox("Ошибка", "Ошибка при выполнении операции", false));
                        return;
                    }
                    SavedDraftsStorage.unload();
                    dispStack.pop(2);
                    dispStack.push(new MessageBox("Сообщение", "Все черновики удалены", false));
                } else if (c == cancelCommand) {
                    dispStack.pop();
                }
            }
        }
    }

    private final class HistoryBox extends List implements CommandListener {

        private Command deleteCommand;
        private Command clearCommand;
        private Form itemForm;
        private StringItem numberItem;
        private StringItem sentItem;
        private StringItem sourceItem;
        private Command sentToEditorCommand;
        private Command sourceToEditorCommand;
        private int currentItemIndex = -1;
        private MessageBox clearWarning;

        public HistoryBox() throws RecordStoreException {
            super("Отправленные", List.IMPLICIT);
            load();
            clearCommand = new Command("Очистить", Command.SCREEN, 30);
            addCommand(okCommand);
            addCommand(backCommand);
            addCommand(clearCommand);
            setSelectCommand(okCommand);
            setCommandListener(this);
            itemForm = new Form("");
            numberItem = new StringItem("Номер: ", "");
            sentItem = new StringItem("Отправленный текст: ", "");
            sourceItem = new StringItem("Исходный текст: ", "");
            itemForm.append(numberItem);
            itemForm.append(sentItem);
            itemForm.append(sourceItem);
            deleteCommand = new Command("Удалить", Command.SCREEN, 30);
            sentToEditorCommand = new Command("Отправл. в редактор", Command.SCREEN, 40);
            sourceToEditorCommand = new Command("Исходн. в редактор", Command.SCREEN, 50);
            itemForm.addCommand(backCommand);
            itemForm.addCommand(deleteCommand);
            itemForm.addCommand(sentToEditorCommand);
            itemForm.addCommand(sourceToEditorCommand);
            itemForm.setCommandListener(this);
        }

        public void load() throws RecordStoreException {
            HistoryStorage.load();
            int count = HistoryStorage.getItemsCount();
            for (int i = 0; i < count; i++) {
                append(HistoryStorage.getHeader(i).getNumber(), null);
            }
        }

        public void commandAction(Command c, Displayable d) {
            if (d == this) {
                if (c == okCommand) {
                    currentItemIndex = getSelectedIndex();
                    if (currentItemIndex < 0) {
                        return;
                    }
                    HistoryStorage.HistoryItemHeader hdr = HistoryStorage.getHeader(currentItemIndex);
                    try {
                        SerializableDate date = hdr.getDate();
                        String number = hdr.getNumber();
                        String sentText = HistoryStorage.getSentText(currentItemIndex);
                        String sourceText = HistoryStorage.getSourceText(currentItemIndex);
                        itemForm.setTitle(date.toString());
                        numberItem.setText(number);
                        sentItem.setText(sentText);
                        sourceItem.setText(sourceText);
                    } catch (RecordStoreException exc) {
                        MessageBox err = new MessageBox("Ошибка", "Ошибка при загрузке сообщения", false);
                        dispStack.push(err);
                        return;
                    }
                    dispStack.push(itemForm);
                } else if (c == backCommand) {
                    HistoryStorage.unload();
                    dispStack.pop();
                } else if (c == clearCommand) {
                    clearWarning = new MessageBox("Подтверждение", "Удалить всю историю?", true);
                    clearWarning.setCommandListener(this);
                    dispStack.push(clearWarning);
                }
            } else if (d == itemForm) {
                if (c == backCommand) {
                    dispStack.pop();
                    currentItemIndex = -1;
                } else if (c == deleteCommand) {
                    try {
                        HistoryStorage.delete(currentItemIndex);
                    } catch (RecordStoreException exc) {
                        MessageBox mb = new MessageBox("Ошибка", "Ошибка при выполнении операции", false);
                        dispStack.push(mb);
                        return;
                    }
                    this.delete(currentItemIndex);
                    currentItemIndex = -1;
                    dispStack.pop();
                } else if (c == sentToEditorCommand) {
                    editBox.setString(sentItem.getText());
                    HistoryStorage.unload();
                    dispStack.popAll();
                    dispStack.push(editBox);
                } else if (c == sourceToEditorCommand) {
                    editBox.setString(sourceItem.getText());
                    HistoryStorage.unload();
                    dispStack.popAll();
                    dispStack.push(editBox);
                }
            } else if (d == clearWarning) {
                if (c == okCommand) {
                    HistoryStorage.unload();
                    MessageBox mb1;
                    try {
                        HistoryStorage.clear();
                        mb1 = new MessageBox("Сообщение", "История успешно очищена", false);
                    } catch (Exception exc) {
                        mb1 = new MessageBox("Ошибка", "Ошибка при очистке истории", false);
                    }
                    dispStack.pop(2);
                    dispStack.push(mb1);
                } else if (c == backCommand) {
                    dispStack.pop();
                }
            }
        }
    }

    private final class MessageBox extends Form {

        public MessageBox(String label, String text, boolean cancel) {
            super(label);
            this.append(text);
            this.addCommand(okCommand);
            if (cancel) {
                this.addCommand(cancelCommand);
            } else {
                this.setCommandListener(new CommandListener() {

                    public void commandAction(Command cmnd, Displayable dsplbl) {
                        if (dispStack.peek() == MessageBox.this) {
                            dispStack.pop();
                        }
                    }
                });
            }
        }
    }
}
